package me.linzh;

import javax.print.DocFlavor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 *
 * NIO demo
 * Created by leolin on 15/12/31.
 */
public class NioServer {

    private String host = "127.0.0.1";
    private int port;
    protected ServerSocketChannel serverSocketChannel;
    protected Selector selector;
//    protected



    private SelectedKeyHandler acceptHandler = new SelectedKeyHandler() {
        @Override
        public void handle(SelectionKey key) {
            ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
            try {
                SocketChannel socketChannel = serverChannel.accept();
                serverChannel.configureBlocking(false);
                socketChannel.register(selector,  SelectionKey.OP_WRITE);
                System.out.println("accepted");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

    private ByteBuffer readBuffer = ByteBuffer.allocate(512);
    private SelectedKeyHandler readHandler = new SelectedKeyHandler() {
        @Override
        public void handle(SelectionKey key) {
            SocketChannel socketChannel = (SocketChannel) key.channel();
            readBuffer.flip();
            try {
                socketChannel.read(readBuffer);
                System.out.println("read: " + new String(readBuffer.array()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

    private NioServer(){}
    public NioServer(String host, int port){
        this.host = host;
        this.port = port;
    }
    public NioServer(int port){
        this.port = port;
    }

    public void start(){
        try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            selector = Selector.open();
            ServerSocket socket = serverSocketChannel.socket();
            InetSocketAddress address = new InetSocketAddress(port);
            socket.bind(address);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            ReactorTask reactorTask = new ReactorTask(selector);
            reactorTask.setAcceptHandler(acceptHandler);
            reactorTask.setReadHandler(readHandler);
            new Thread(reactorTask).run();
            Thread.currentThread().join();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        new NioServer(2333).start();
    }
}


